package com.education.platform.management.service.impl;

import com.alibaba.fastjson.JSON;
import com.education.platform.common.encrypt.MD5Util;
import com.education.platform.common.exception.AssertException;
import com.education.platform.common.exception.BusinessException;
import com.education.platform.common.redis.RedisUtils;
import com.education.platform.common.util.BeanUtil;
import com.education.platform.common.util.StringUtils;
import com.education.platform.common.util.UUIDGenerator;
import com.education.platform.dao.SysMenuDao;
import com.education.platform.dao.SysUserRoleDao;
import com.education.platform.dao.entity.SysMenuDO;
import com.education.platform.dao.entity.SysUserDO;
import com.education.platform.dao.entity.SysUserRoleDO;
import com.education.platform.management.config.ThreadUser;
import com.education.platform.management.constants.RedisCacheConstant;
import com.education.platform.management.service.LoginService;
import com.education.platform.management.service.SysUserService;
import com.education.platform.management.service.entity.LoginSuccessDTO;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description : 登陆
 */
@Service
public class LoginServiceImpl implements LoginService {

    private Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);


    @Value("${token.expire}")
    private int tokenExpire;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysMenuDao sysMenuDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginSuccessDTO login(String userName, String passWord) {

        SysUserDO query = new SysUserDO();
        query.setUserName(userName);
        query.setPassWord(passWord);
        SysUserDO userDO = sysUserService.get(query);
        if(userDO == null){
            AssertException.throwBusinessEp("用户名或密码不正确");
        }
        //获取用户的菜单权限
        List<SysMenuDO> menuDOS  =sysMenuDao.getMenusByUserId(userDO.getId());
        //token生成
        String token = createToken();
       //保存登录信息到redis缓存
        saveLoginCache( token, JSON.toJSONString(userDO));
        LoginSuccessDTO result = buildLoginSuccess( userDO,token,menuDOS);

        //角色id
        SysUserRoleDO queryRole = new SysUserRoleDO();
        queryRole.setUserId(userDO.getId());
        List<SysUserRoleDO> relUserRoles = sysUserRoleDao.getList(queryRole);
        if(CollectionUtils.isNotEmpty(relUserRoles)){
            List<Integer> roleIds = relUserRoles.parallelStream().map(SysUserRoleDO::getRoleId).collect(Collectors.toList());
            result.setRoleId(roleIds.get(0));
        }
        return result;
    }

    /**
     * 退出登录
     *
     * @return
     */
    @Override
    public void logout() {
      String tokenRedisKey =  ThreadUser.getUserTokenRedisKey();
      if(StringUtils.isEmpty(tokenRedisKey)){
          AssertException.throwBusinessEp("当前未登录！");
      }else{
          redisUtils.del(tokenRedisKey);
      }
    }

    /**
     * 修改密码
     *
     * @param oldPassword
     * @param newPassword
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePwd(String oldPassword, String newPassword) {
        if(StringUtils.isEmpty(oldPassword)){
            throw new BusinessException("原始密码不能为空");
        }
        if(StringUtils.isEmpty(newPassword)){
            throw new BusinessException("新密码不能为空");
        }
        Integer userId = ThreadUser.getUserId();
        SysUserDO userDO = sysUserService.getById(userId);
        if(userDO == null){
            throw new BusinessException("用户不存在");
        }
        if(!oldPassword.equals(userDO.getPassWord())){
            throw new BusinessException("原始密码不正确");
        }
        SysUserDO update  = new SysUserDO();
        update.setId(userDO.getId());
        update.setPassWord(newPassword);
        update.setUpdateTime(new Date());
        update.setUpdateBy(ThreadUser.getUserName());
        sysUserService.updateById(update);
        //删除缓存token
        String tokenRedisKey =  ThreadUser.getUserTokenRedisKey();
        redisUtils.del(tokenRedisKey);

    }

    private LoginSuccessDTO buildLoginSuccess(SysUserDO user, String token, List<SysMenuDO> menuDOS ) {
        LoginSuccessDTO success = BeanUtil.convert(user, LoginSuccessDTO.class);
        success.setToken(token);
        success.setMenuDOS(menuDOS);
        return success;
    }




    /**
     * 保存缓存
     * @param token
     * @param jsonUser
     */
    private void saveLoginCache( String token, String jsonUser) {
        String tokenRedisKey = RedisCacheConstant.KEY_APP_TOKEN +token;
        redisUtils.setString(tokenRedisKey,tokenExpire , jsonUser);
        ThreadUser.setUserJson(jsonUser);
        ThreadUser.setUserTokenRdisKey(tokenRedisKey);
    }

    /**
     * 创建token
     *
     * @return
     */
    private String createToken() {
        return MD5Util.encrypt( String.valueOf(System.currentTimeMillis()), UUIDGenerator.getUUID());

    }


}
